

#include <string>
#include <vector>
#include "dataStream.h"

#ifndef _H_GAMEDATA
#define _H_GAMEDATA


enum eventType
{//MAIN Events.
	//Some events have "secondary" events
	//See eventNumb below
ev_create= 0,//Kind is always =
ev_destroy= 1, //Kind is always 0 
ev_step= 3, //Has different kinds
ev_alarm= 2, //Kind is from 0 to 11
ev_keyboard= 5, //Kind is the key code
ev_mouse= 6, //Has different Kinds
ev_collision= 4, //Kind is the index of the other object to trigger the collision
ev_other= 7, //Has different kinds
ev_draw= 8,
ev_keypress= 9,//Kind is the key code
ev_keyrelease= 10,//Kind is the key code
ev_trigger= 11
};

enum eventKind
{
//ev_mouse event Kinds
ev_left_button= 0,
ev_right_button= 1,
ev_middle_button= 2,
ev_no_button= 3,
ev_left_press= 4,
ev_right_press= 5,
ev_middle_press= 6,
ev_left_release= 7,
ev_right_release= 8,
ev_middle_release= 9,
ev_mouse_enter= 10,
ev_mouse_leave= 11,
ev_mouse_wheel_up= 60,
ev_mouse_wheel_down= 61,
ev_global_left_button= 50,
ev_global_right_button= 51,
ev_global_middle_button= 52,
ev_global_left_press= 53,
ev_global_right_press= 54,
ev_global_middle_press= 55,
ev_global_left_release= 56,
ev_global_right_release= 57,
ev_global_middle_release= 58,
ev_joystick1_left= 16,
ev_joystick1_right= 17,
ev_joystick1_up= 18,
ev_joystick1_down= 19,
ev_joystick1_button1= 21,
ev_joystick1_button2= 22,
ev_joystick1_button3= 23,
ev_joystick1_button4= 24,
ev_joystick1_button5= 25,
ev_joystick1_button6= 26,
ev_joystick1_button7= 27,
ev_joystick1_button8= 28,
ev_joystick2_left= 31,
ev_joystick2_right= 32,
ev_joystick2_up= 33,
ev_joystick2_down= 34,
ev_joystick2_button1= 36,
ev_joystick2_button2= 37,
ev_joystick2_button3= 38,
ev_joystick2_button4= 39,
ev_joystick2_button5= 40,
ev_joystick2_button6= 41,
ev_joystick2_button7= 42,
ev_joystick2_button8 = 43,
//End ev_mouse kinds
//ev_other kinds
ev_outside= 0,
ev_boundary= 1,
ev_game_start= 2,
ev_game_end= 3,
ev_room_start= 4,
ev_room_end= 5,
ev_no_more_lives= 6,
ev_no_more_health= 9,
ev_animation_end= 7,
ev_end_of_path= 8,
ev_close_button= 30,
ev_user0= 10,
ev_user1= 11,
ev_user2= 12,
ev_user3= 13,
ev_user4= 14,
ev_user5= 15,
ev_user6= 16,
ev_user7= 17,
ev_user8= 18,
ev_user9= 19,
ev_user10= 20,
ev_user11= 21,
ev_user12= 22,
ev_user13= 23,
ev_user14= 24,
ev_user15= 25,
//end ev_other kinds
//ev_step kinds
ev_step_normal= 0,
ev_step_begin= 1,
ev_step_end= 2
//End ev_step kinds
};



struct gameSettingsDef
{
	bool startInFullScreen; //Does the game start in full screen?
	bool interpolateColors; //Interpolate colors between pixels
	bool dontDrawBorder; //Don't draw border in windowed mode
	bool displayCursor; //Display the cursor
	int Scaling; //-1: Keep aspect ratio, 0: Full Scale, 1-999 = Fixed Scale %
	bool allowWindowResize; //Allow the player to resize the game window
	bool alwaysOnTop; //Let the game window always stay on top.
	int colorOutsideRoom; //Color outside the room region
	bool setResolution; //set the resolution of the screen
	char colorDepth; //Color depth 0: No change, 1: 16-bit, 2: 32-bit
	char Resolution; //Resolution: 0: No change, 1: 320x240, ..., 6: 1600x1200
	char Frequency; //Frequency: 0: No change, 1: 60, ..., 5: 120
	bool dontShowButtons; //Dont show the buttons in the window caption
	bool useSync; //Use synchronization to avoid tearing
	bool disableScreen; //disable screensavers and power saving actions
	bool letF4; //let F4 switch between screen modes.
	bool letF1; //Let F1 show game information
	bool letEsc; //Let Esc end the game
	bool letF5; //Let F5 save the game and F6 load a game
	bool letF9; //Let F9 take a screenshot of the game
	bool treatCloseAsEsc; //Treat the close button as the <Esc> key
	char processPriority; //Game process priority (0: normal, 1: High, 2: Highest)
	bool freezeUnfocus; //Freese the game when form looses focus
	char loadingBar; //Loading progress bar (0: no Bar, 1: default bar, 2: custom bar)
	dataStream* backImageData; //The data for the back image of the loading bar
	dataStream* frontImageData; //The data for the front imahe
	bool customLoadImage; //Show your own image while loading
	dataStream* loadBarImageData; //The data for the loading bar image
	bool imageTransparent; //Make image partially transparent
	unsigned char translucentAlpha; //Make translucent with alpha value
	bool scaleProgressBar; //Scale progress bar image
	dataStream* iconData; //data for the icon for the game
	bool displayErrors; //Display error messages
	bool errorLog; //erite error messages to file game_errors.log
	bool abortErrors; //Abort on all error messages
	bool unitializedVarsZero; //Treas uninitialized variables as 0
	std::string Author; //Author of the game
	std::string Version; //Version of the game
	double lastChanged; //Last Changed date and time
	std::string Information; //Game information
	unsigned char majorVersion; //Version Information: Major
	unsigned char minorVersion; ////Version Information: Minor
	unsigned char releaseVersion; ////Version Information: realease
	unsigned char buildVersion; ////Version Information: Build
	std::string Company; //Version Information: Company
	std::string Product; //Version Information: Product
	std::string Copyright; //Version Information: Copyright
	std::string Description; //Version Information: Description
	double lastSettingsChange; //Last time Global Game Settings were changed.
};

struct constantDef
{
	std::string Name;
	std::string Value;
};
struct scriptDef
{
	std::string Name; //Name of the script
	double lastChanged; //Last time it was changed
	std::string Script; //The text of the script
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
};

struct subImageDef
{
	int Width; //Width
	int Height; //Height
	dataStream* imageData; //Data for the image
};

struct spriteDef
{
	std::string Name; //Name of the sprite
	double lastChanged; //Last time it was changed
	int originX; //X origin
	int originY; //Y origin
	std::vector<subImageDef*> subImages; //All the sub images
	unsigned char shape; //Shape (0: Precise, 1:Rectangle,  2:Disk, 3: Diamond)
	unsigned char alphaTolerance; //Alpha Tolerance..
	bool seperateCollisionMasks; //Seperate collision masks
	unsigned char boundingBox; //BoundingBox 0: automatic, 1:Full, 2: Manual);
	int Left; //BoundingBox Left
	int Right; //BoundingBox Left
	int Bottom; //BoundingBox Left
	int Top; //BoundingBox Left
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
};

struct soundDef
{
	std::string Name; //Name of the sound
	double lastChanged; //LAst changed
	int Kind; //-1:None, 0:"Wave", 1:"Midi", 2:"Mp3", 10:"Unknown")
	std::string fileType; //Filetype (like .mp3)
	std::string fileName; //Name of file (no path)
	dataStream* musicData; //Music Data NULL means there is no music file chosen or w/e
	int Effects; //Effects on the audio (Chorus:1, Echo:2, Flanger:4, Gargle:8, Reverb:16)
	double volume; //Self explanitory 0 means no volume, 1 means full
	double Pan; //Pan (-1 to 1, 0 means center)
	bool preload; //Preload the sound?
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
};

struct backgroundDef
{
	std::string Name; //Name of the background
	double lastChanged; //Last modified
	bool tileSet; //Use as tile set
	int tileWidth; //Width of tiles
	int tileHeight; //Height of tiles
	int hOffset; //Horizontal offset
	int vOffset; //Vertical offset
	int hSep; //Horizontal seperation
	int vSep; //Vertical seperation
	int Width; //Width of the BG
	int Height; //Height of the BG
	dataStream* imageData; //image Data for the BG raw BGRA
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.

};
struct pathPointsDef
{
	double x;
	double y;
	double speed;
};
struct pathDef
{
	std::string Name; //Name of path
	double lastChanged; //Last modified
	unsigned char Kind; //Connection Kind 0:Straight 1: Smooth
	bool Closed; //Is the path closed?
	int Precision; //Precision
	int roomIndexBG; //Room index to show as background
	int snapX; //Snap X;
	int snapY; //Snap Y
	std::vector<pathPointsDef*> Points; //The points on the path
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
};

struct fontDef
{
	std::string Name; //Name of font
	double lastChanged; //Last time changed
	std::string fontName; // The font name ("Arial" ,etc)
	short Size; //Font size
	bool Bold; //Bold
	bool Italic; //Italic?
	int charRangeBegin; // Character range begin
	int charRangeEnd; // Character range end
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
};

struct roomBGDef
{
	bool Visible; //Visible when room starts
	bool foregroundImage; //Foreground Image?
	int backgroundIndex; //backgroud Index
	int X; // X position
	int Y; //Y position
	bool tileH; //Tile horizontally
	bool tileV; //Tile vertically
	int hSpeed; //H. Speed
	int vSpeed;//V Speed
	bool Stretch; //Stretch the background?

};
struct roomViewsDef
{
	bool visibleStart; //Visible when room starts?
	int viewX; //X position
	int viewY; //Y position
	int viewW; //Width
	int viewH; //Height
	int portX; //port X
	int portY; //port Y
	int portW; //port width
	int portH; //port height
	int hBorder; //Hbor.
	int vBorder; //vBorder.
	int Hsp; //Hspeed
	int Vsp; //VSpeed
	int objFollow; //Object to follow (-1 for none.)
};
struct roomInstancesDef
{
	int X; //X position
	int Y; //Y position
	int objectIndex; //Index of the object
	int ID; //ID (starts with 100001)
	std::string creationCode; //Creation code for this instance
	bool Locked; //Is this object locked?
};
struct roomTilesDef
{
	int X; //X position
	int Y; //Y position
	int backgroundIndex; //Index of the background
	int tileX; //tileX position on background
	int tileY; //tileY position on the background
	int Width; //Width of the tile
	int Height; //Height of the tile;
	int Depth; //Depth
	int ID; //Tile ID (starts at 10000001)
	bool Locked; //Is this tile locked?


};
struct roomDef
{
	std::string Name; //Name of room
	double lastChanged; //Last time changed
	std::string roomCaption; //Caption for the room
	int Width; //Room width
	int Height; //Room Height
	int snapX; //Snap X
	int snapY; //Snap Y
	bool isometricGrid; //Turn the grid into an isometric grid
	short Speed; //Speed of the room
	bool Persistent; //Persistent room..
	int backgroundColor; //Background color
	bool drawBackgroundColor; //Draw background color
	std::string creationCode; //Creation code for the room
	std::vector<roomBGDef*> Backgrounds; //List of backgrounds
	bool enableViews; //Enable the use of views
	std::vector<roomViewsDef*> Views; //List of the views
	std::vector<roomInstancesDef*> Instances; //List of instances
	std::vector<roomTilesDef*> Tiles; //List of tiles.
	bool rememberRoomEditorInfo; //Remember settings?
	int roomEditorWidth; //Room editor width
	int roomEditorHeight; //Room editor height
	bool showGrid; //Show the grid?
	bool showObjects; //display objects?
	bool showTiles; //Show tiles?
	bool showBackgrounds; //Show backgrounds?
	bool showForegrounds; //Show forgrounds?
	bool showViews; //Show views?
	bool deleteUnderlyingObjects; //Delete underlying objects?
	bool deleteUnderlyingTiles; //Delete underlying tiles?
	unsigned char Tab; //Tab that is currenty in focus
							//0: Objects, 1: Settings, 2:Tiles, 3:Backgrounds, 4:Views
	int xPosScrollBar; //Scroll bar position for horizontal scroll bar
	int yPosScrollBar; //Scroll bar position for vertical scroll bar
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.



};

struct triggerDef
{
	std::string Name; //Name of trigger
	std::string Condition; //Confition as a string
	unsigned char checkMoment; //Moment to check (0:Begin, 1:Middle, 2:End)
	std::string constantName; //Name of the trigger constant..
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.

};
struct objectActionDef
{
	int libraryID; //ID of the library this action came from..
	int ID; //The ID of the action
	int Kind; //Normal, Begin block, else, etc.)
	bool maybeRelative; //Is action relative to something?
	bool Question; //Is a question?
	bool appliesToSomething; //Applies to something else?
	int Type; //Type of action 0: Nothing, 1: Function, 2: Code
	std::string functionName; //Name of the function
	std::string functionCode; //the function code
	int argumentsUsed; //How many arguments were used
	int argumentKind[8]; //The kind of  arguments
	int appliesToObject; //Applies to -1 (Self), -2 for Other
	bool isRelative; //Is this action relative?
	std::string argumentValues[8]; //The 8 argument values


};
struct objectEventDef
{
	int eventType; //The type of event ("Create, Draw, etc"). The "Main events"
	int eventKind; //The secondary type of event (eg which alarm, which key..)
	std::vector<objectActionDef*> Actions; //Actions in this event..
};
struct objectDef
{
	std::string Name; //Name of object
	double lastChanged; //Last time object was changed
	int spriteIndex; //Sprite index
	bool Solid; //Solid?
	bool Visible; //Visible?
	int Depth; // Depth of object
	bool Persistent; //Persistent
	int parentObject; //Parent object idnex (-100 means none);
	int maskSpriteIndex; //Sprite index of the collision mask
	bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
	std::vector<objectEventDef*> Events; //Events for this object

};

struct includedFilesDef
{
	double lastChanged; //LAst time it was changed
	std::string fileName; //File name for the file
	std::string filePath; //File Path
	bool originalFile; //Weather an original file was chosen or not
	int originalFileSize; //Size of original file
	bool storedInGMK; //Was this stored in the gmk file?
	dataStream* fileData; //Data if the data was stored in GMK
	unsigned char exportType; //Where to export 0: Dont, 1:Tempdir, 2:working Dir, 3: following folder
	std::string folderExport; //Folder to export to
	bool overWrite; //overwrite if file exists?
	bool freeMem; //Free memory after export?
	bool removeGameEnd; //Remove at game end?


};
struct gameInfoDef
{
	int backgroundColor; //Background color
	bool seperateWindow; //Show in seperate window?
	std::string formCaption; //Caption for the gameInformation window
	int positionLeft; //Left position
	int positionTop; //Right position
	int positionWidth; //Width 
	int positionHeight; //Height
	bool showWindowBorder; //Show the window border/Caption?
	bool allowResize; //Allow players to resize?
	bool stayOnTop; //Always stay on top
	bool stopGame; //Stop the game while showing?
	double lastChanged; //Last time changes
	std::string gameInformationRTF; //Game information in Rich tecx format

};

struct timeLineMomentDef
{
	std::vector<objectActionDef*>  actionsList; //List of actions for this moment in the timeline
	int moment; //Moment step (eg step 0, etc);

};
struct timelineDef
{
 std::string TimelineName; //Name of the Time line
 bool exists; //Does this resource exist? If this is false, it means all the other data is invalid and should not be used.
 double lastChanged; //Last time it was changed
 std::vector<timeLineMomentDef*> momentList; //List of moments for the timeline.
};
struct ResourceTreeDef
{
	unsigned char Status; //Status of the node (1: Primary, 2: Group, 3: Secondary);
	unsigned char Group; //What group its in (1-13);
	int Index; //Index
	std::string Name; //Name of the node
	std::vector<ResourceTreeDef*> Contents; //Recursive contents.
};

class gameData
{
public:
	//Data
	int gameID; //Game identifier
	gameSettingsDef gameSettings; //Game Settings
	std::vector<constantDef*> Constants; //List of constants
	std::vector<scriptDef*> Scripts; //List of scripts..
	std::vector<spriteDef*> Sprites; //List of sprites
	std::vector<soundDef*> Sounds; //List of sounds
	std::vector<timelineDef*> Timelines; //List of timelines
	std::vector<backgroundDef*> Backgrounds; //List of Backgrounds
	std::vector<pathDef*> Paths; //List of paths
	std::vector<fontDef*> Fonts; //List of fonts
	std::vector<roomDef*> Rooms; //List of rooms
	std::vector<triggerDef*> Triggers; //List of triggers
	std::vector<objectDef*> Objects; //List of objects
	std::vector<includedFilesDef*> includedFiles; //List of included files
	std::vector<std::string> Packages; //Packages (Extensions)
	std::vector<ResourceTreeDef*> ResourceTree; //The resource tree
	gameInfoDef gameInformation; //Game information
	std::vector<std::string> libCreationCodes;
	std::vector<int> roomExecutionOrder; //List of the executable rooms in order..
	int lastTilePlaced; //ID of last tile placed
	int lastInstancePlaced;//ID of last Instance Placed
	double triggersChanged; //Last time triggers were changed
	double constantsChanged; //Last time constants were changed

	//Will set "default values" for game data. 
	void setDefaults();
	//Root Nodes
	ResourceTreeDef *spritesNode;
	ResourceTreeDef *soundsNode;
	ResourceTreeDef *backgroundsNode;
	ResourceTreeDef *pathsNode;
	ResourceTreeDef *scriptsNode;
	ResourceTreeDef *fontsNode;
	ResourceTreeDef *timelinesNode;
	ResourceTreeDef *objectsNode;
	ResourceTreeDef *roomsNode;


	//Used for parsing the file..
	void Parse(std::string fName); //Parse the indicated file
	void Write(std::string fName); //Writes the Gm8 file.

	//Stuff for defragging
	void defragResources(); //Defrags resources

private:
	void actionFix(int argumentKind, int oldIndex, int newIndex); //Iterates Actions and repairs broken indexes
};


#endif